`timescale  1 ns/1 ps

module nor_flash_tb ();

`include "axi_stream_bfm.svh"
`include "axi_stream_drive.svh"
`include "../src/nor_flash_macro.v"


reg                     clk = 0;
always
    #(1s/100_000_000/2) clk = ~clk;

reg                     rst = 0;
initial
begin
    #1us; rst = 1;
    #1us; rst = 0;
end

localparam              ADDR_W = 26;
localparam              DATA_W = 16;

logic [07:00]        flash_cmd = 0;
logic [ADDR_W-1:00]  flash_addr;     // 需要操作的flash地址

logic                s_axis_tvalid;
logic                s_axis_tlast;
logic                s_axis_tready;
logic [DATA_W-1:00]  s_axis_tdata;

logic                nor_wait;

logic                nor_adv_n;    // address valid
logic                nor_ce_n;     // chip enable
logic                nor_oe_n;
logic                nor_we_n;
logic                nor_wp_n;   // write protect

logic                nor_clk;
logic                nor_rst_n;

logic [ADDR_W-1:00]  nor_addr;
tri [DATA_W-1:0] nor_data = 100'bz;
assign (weak1, weak0) nor_data = 0;

defparam  nor_flash_tb.nor_flash_commandEx01.FRAME_LEN = 4;

axi_stream_bfm axi_stream_if 
(
    .s_aclk       (    clk                                   ),
    .s_aresetn    (    ~rst                                  )
);

axi_stream_drive axi_stream_drive_h;

initial
begin
    axi_stream_drive_h = new(axi_stream_if);
    //axi_stream_if.m_axis_tready = 1;

    @ (posedge axi_stream_if.s_aclk);
    #5us axi_stream_drive_h.write_increase_frame(7, 5);
end


initial
begin
    //#5us;
    //@ (posedge clk);
    //flash_cmd = 8'h11;
    //@ (posedge clk);
    //@ (posedge clk);
    //flash_cmd = 0;

    #5us;
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = `FLASH_ERASE_BLOCK;
    @ (posedge axi_stream_if.s_aclk);
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = 0;

    #10us;
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = `FLASH_BUFFER_PROGRAM;
    @ (posedge axi_stream_if.s_aclk);
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = 0;

    #800us;
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = `FLASH_READ_PAGE;
    @ (posedge axi_stream_if.s_aclk);
    @ (posedge axi_stream_if.s_aclk);
    flash_cmd = 0;
end

nor_flash_command #
(
    .ADDR_W          (  26                                   ),
    .DATA_W          (  16                                   )
)
nor_flash_commandEx01
(
    .clk             (  axi_stream_if.s_aclk                 ),
    .rst             (  ~axi_stream_if.s_aresetn             ),
    .flash_cmd       (  flash_cmd                            ),
    .flash_addr      (  26'h20                               ),
    .s_axis_tvalid   (  axi_stream_if.m_axis_tvalid          ),
    .s_axis_tlast    (  axi_stream_if.m_axis_tlast           ),
    .s_axis_tready   (  axi_stream_if.m_axis_tready          ),
    .s_axis_tdata    (  axi_stream_if.m_axis_tdata[15:00]    ),

    .m_axis_tvalid   (                                       ),
    .m_axis_tlast    (                                       ),
    .m_axis_tready   (   1'b1                                ),
    .m_axis_tdata    (                                       ),
    .nor_wait        (  nor_wait                             ),
    .nor_rst_n       (  nor_rst_n                            ),
    .nor_adv_n       (  nor_adv_n                            ),
    .nor_ce_n        (  nor_ce_n                             ),
    .nor_oe_n        (  nor_oe_n                             ),
    .nor_we_n        (  nor_we_n                             ),
    .nor_wp_n        (  nor_wp_n                             ),
    .nor_clk         (  nor_clk                              ),
    .nor_addr        (  nor_addr                             ),
    .nor_data        (  nor_data                             )
);

//defparam  nor_flash_tb.nor_flash_commandEx01.PROGRAM_256WORD_TIME = 100;
x28fxxxp30 DUT
(
    .A                (    nor_addr                          ),
    .DQ               (    nor_data                          ),
    .W_N              (    nor_we_n                          ),
    .G_N              (    nor_oe_n                          ),
    .E_N              (    nor_ce_n                          ),
    .L_N              (    nor_adv_n                         ),
    .K                (    nor_clk                           ),
    .WAIT             (    nor_wait                          ),
    .WP_N             (    nor_wp_n                          ),
    .RP_N             (    nor_rst_n                         ),
    .VDD              (    36'h6a4                           ),
    .VDDQ             (    36'h6a4                           ),
    .VPP              (    36'h7d0                           ),
    .Info             (    1'b1                              )
);
endmodule
